package com.mmall.admin.shiro;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mmall.common.util.SpringUtil;
import com.mmall.facade.cache.CacheFeignService;
import com.mmall.common.base.ServerResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.ValidatingSession;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.subject.support.DefaultSubjectContext;
import org.springframework.stereotype.Component;

import java.io.Serializable;

/**
 * @author gg
 * @version SessionDaoConfig.java, v 0.1 2019-05-09 10:51 gg
 */
@Slf4j
@Component
public class SessionDaoConfig extends EnterpriseCacheSessionDAO {


    @Override
    protected Serializable doCreate(Session session) {
        Serializable sessionId = this.generateSessionId(session);
        MmallSimpleSession simpleSession = (MmallSimpleSession) session;
        simpleSession.setId(sessionId.toString());
        return sessionId;
    }

    @Override
    protected Session doReadSession(Serializable sessionId) {
        sessionId = DevTool.getDevSessionKey(sessionId);
        CacheFeignService cacheFeignService = SpringUtil.getBean(CacheFeignService.class);
        ServerResponse response = cacheFeignService.getSession(sessionId.toString());
        Object data = response.getData();
        if (data != null) {
            JSONObject parse = JSONObject.parseObject(data.toString());
            MmallSimpleSession mmallSimpleSession = new MmallSimpleSession();
            mmallSimpleSession.setId(parse.getString("id"));
            mmallSimpleSession.setExpired(parse.getBoolean("expired"));
            mmallSimpleSession.setStartTimestamp(parse.getDate("startTimestamp"));
            mmallSimpleSession.setStopTimestamp(parse.getDate("stopTimestamp"));
            mmallSimpleSession.setLastAccessTime(parse.getDate("lastAccessTime"));
            mmallSimpleSession.setTimeout(parse.getLong("timeout"));
            mmallSimpleSession.setHost(parse.getString("host"));
            JSONObject shiroUserJson = parse.getJSONObject("shiroUser");
            ShiroUser shiroUser = new ShiroUser();
            shiroUser.setName(shiroUserJson.getString("name"));
            shiroUser.setUsername(shiroUserJson.getString("username"));
            shiroUser.setRoleIds(shiroUserJson.getString("roleIds"));
            mmallSimpleSession.setShiroUser(shiroUser);
            return mmallSimpleSession;
        }
        return null;
    }


    @Override
    protected void doUpdate(Session session) {
        CacheFeignService cacheFeignService = SpringUtil.getBean(CacheFeignService.class);
        if (session instanceof ValidatingSession) {
            if (((ValidatingSession) session).isValid()) {
                //注意设置超时时间
                MmallSimpleSession simpleSession = (MmallSimpleSession) session;
                Object attribute = session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
                if (attribute != null) {
                    SimplePrincipalCollection spc = (SimplePrincipalCollection) attribute;
                    Object primaryPrincipal = spc.getPrimaryPrincipal();
                    ShiroUser shiroUser = (ShiroUser) primaryPrincipal;
                    if (shiroUser != null) {
                        ShiroUser cacheUser = new ShiroUser();
                        cacheUser.setUsername(shiroUser.getUsername());
                        cacheUser.setRoleIds(shiroUser.getRoleIds());
                        cacheUser.setName(shiroUser.getName());
                        simpleSession.setShiroUser(cacheUser);
                    }
                }
                cacheFeignService.updateSession(session.getId().toString(), JSON.toJSONString(simpleSession));
            } else {
                cacheFeignService.deleteSession(session.getId().toString());
            }
        } else {
            cacheFeignService.updateSession(session.getId().toString(), JSON.toJSONString(session));
        }
    }

    @Override
    protected void doDelete(Session session) {
        CacheFeignService cacheFeignService = SpringUtil.getBean(CacheFeignService.class);
        cacheFeignService.deleteSession(session.getId().toString());
    }
}